繼續昨天 git commit
的說明,在輸入 git commit
後會出現一個文字編輯器的畫面,列出這次提交工作目錄中的檔案異動狀態,如同之前 git status
指令所介紹的,並要求使用者輸入提交訊息。如先前所提過的,文字編輯器種類可透過 git config
設置。畫面範例如下:
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Your branch is up to date with 'origin/master'.
#
# Changes to be committed:
# deleted: README
# modified: Rakefile
# new file: new-file.txt
#
# Changes not staged for commit:
# modified: lib/simplegit.rb
#
# Untracked files:
# no-commit.txt
#
接下來在這個文字編輯區域的最上方輸入提交訊息,通常是告知這次提交中我們做了什麼事,例如完成了什麼功能,或者解掉了什麼 bug。一般團隊使用的情境下會對提交訊息的內容格式有所規範。如果沒有輸入任何訊息,那麼這次提交就會被放棄。我們也可以在 git commit
指令中直接使用 -m
旗標,並加入提交訊息內容參數,例如:
$ git commit -m "initial commit"
如此 Git 就會直接完成這次提交,而不會出現文字編輯畫面。
有些檔案我們不想讓 Git 納管,例如密碼金鑰或是一些暫存檔,但是每次要提交時它們都會出現在 untracked flles 段落。我們可以使用 .gitignore
這個檔案來忽略它們。在工作目錄中新建 .gitignore
這個檔案,然後記下不想要被納管的檔案名稱或類型,這麼一來它們就不會出現在 untracked files 中,git add -A
也不會將它們加入 index。.gitignore
的範例如下:
# 忽略 .tmp 結尾的檔案
*.tmp
# 忽略 secret-key 這個檔案
secret-key
其中 # 開頭的部分是註解。.gitignore
只要存在就會發生效果,不過通常會將它一併納管,因此要記得提交它。.gitignore
更詳細的說明請參考 https://git-scm.com/docs/gitignore。
在前面我們說明了 Git 兩階段提交的概念。可以把它想成是一個檔案的狀態改變,首先在工作目錄發生,接下來用 git add
將這個改變更新到暫存區或 index,最後用 git commit
將改變更新至儲存庫。過程可參考下面這張圖:
瞭解 Git 如何提交後,我們要看一下在經過多次提交後,如何查看這些歷史提交的內容。查看提交內容的指令是
$ git log
它會依順序列出先前的提交,最近的提交在上,較早的提交在下,所以我用「上下」作為第一個維度的方向。提交內容包括提交的 Hash 字串、提交者、提交時間及提交訊息,範例如下:
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the verison number
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 10:31:28 2008 -0700
first commit
commit 後面有一串英數字,它是一個 Hash 字串,是將提交當下的狀態經過某種 hash 演算法計算得來,可以把它當作是這個提交的名稱。git log
有很多不同的參數,每個參數都會略為影響輸出的結果,有可能是對提交輸出更多的資訊,像是那些檔案狀態有更改,也有可能是輸出格式的改變。我覺得這也是讓大家認為 Git 很困難的原因之一,就是它的指令參數實在是太多了。git log
因為只是輸出資訊用的指令,用錯參數也就算了,但關於那些會改變工作目錄或儲存庫的指令,用錯參數可能就會造成意料之外的結果。不過也因為 Git 的功能十分強大,幾乎每個操作都會有回復的方法,所以如果操作錯誤時也不用慌,上網找找看回復上一個狀態的方法是什麼。我覺得這也是一個練功的方式,進行每一個操作時,都想想看回復上一個狀態要怎麼作,這樣應該很快就能功力大增了。
回到 git log
,在 pro git 中有介紹一些常用的參數,例如想知道每個 commit 更詳細的訊息,可以加上 --patch
(-p
) 或者 --stat
這兩個選項。-p
會以 diff 的方式詳列檔案更改的內容,例如:
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the verison number
diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
spec = Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = "simplegit"
- s.version = "0.1.0"
+ s.version = "0.1.1"
s.author = "Scott Chacon"
s.email = "schacon@gmail.com"
s.summary = "A simple gem for using Git in Ruby code."
--stat
會列出有那些檔案變動的訊息。
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 10:31:28 2008 -0700
first commit
README | 6 ++++++
Rakefile | 23 +++++++++++++++++++++++
lib/simplegit.rb | 25 +++++++++++++++++++++++++
3 files changed, 54 insertions(+)
--decorate
會列出引用 (refs) 指標,就是在 hash 字串旁的 HEAD、master 等資訊,之後會再說明。
commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the verison number
如果我們不想列出所有的提交訊息,可以用 -<n>
選項,只列出最近 n 筆的提交訊息。
另外是更改輸出樣式的指令,如 --graph
、--pretty=oneline
等選項,例如:
* ca82a6dff817ec66f44342007202690a93763949 changed the verison number
* 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
* a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
git log
其他的參數就請大家自行查閱。今天最後我們介紹一個和提交相關的指令,用來重做上一次提交。例如在一個新的提交後又更動了一些檔案,但想將這些更動一併納入上一個提交,而不是放在另一個新提交中,就可以用 git commit --amend
這個指令,在提交記錄中它會以一個新的提交來取代上一次的提交,並同時納入這兩次提交的內容。
今天先介紹到這裡,明天我們接著研究一些「回復先前狀態」的操作。